package leetcode.tree;

import java.util.HashMap;
import java.util.Map;

/**
 * 给定两个整数数组 preorder 和 inorder ，其中 preorder 是二叉树的先序遍历， inorder 是同一棵树的中序遍历，请构造二叉树并返回其根节点。
 * <p>
 * <p>
 * <p>
 * 示例 1:
 * <p>
 * <p>
 * 输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
 * 输出: [3,9,20,null,null,15,7]
 * 示例 2:
 * <p>
 * 输入: preorder = [-1], inorder = [-1]
 * 输出: [-1]
 * <p>
 * <p>
 * 提示:
 * <p>
 * 1 <= preorder.length <= 3000
 * inorder.length == preorder.length
 */
public class LeetCode105_BuildTree {

    Map<Integer, Integer> inOrderIndex;

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        inOrderIndex = new HashMap<>();
        for (int i = 0; i < inorder.length; i++) {
            inOrderIndex.put(inorder[i], i);
        }
        return buildTree(preorder, inorder, 0, preorder.length - 1, 0, preorder.length - 1);
    }

    public TreeNode buildTree(int[] preorder, int[] inorder, int pl, int pr, int il, int ir) {

        if (pl > pr || il > ir) {
            return null;
        }

        TreeNode root = new TreeNode(preorder[pl]);
        // 当前节点，第一个节点根节点
        int k = inOrderIndex.get(preorder[pl]);
        // 左子树的数量
        int leftCount = k - il;

        root.left = buildTree(preorder, inorder, pl + 1, pl + leftCount, il, k - 1);
        root.right = buildTree(preorder, inorder, pl + leftCount + 1, pr, k + 1, ir);

        return root;
    }
}
